﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using PMS.Entity;
using PMS.Resources;
using DevExpress.XtraEditors;
using DevExpress.XtraTab;
using DevExpress.XtraLayout;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid;
using DevExpress.Utils;
using DevExpress.XtraGrid.Columns;
using DevExpress.XtraGrid.Views.Base;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using PMS.Win;
using System.Data.OleDb;
using System.Data;
using PMS.Utils;
using System.Threading;
using System.Configuration;
using System.Data.SqlClient;

namespace PMS.Win
{
    public partial class FormEntryBase : BaseForm
    {
        #region Const
        public readonly Color REQUIRED_FIELD_COLOR = PMS.Resources.Constants.REQUIRE_COLOR;
        public readonly Color DISABLE_FIELD_COLOR = PMS.Resources.Constants.READ_ONLY_COLOR;
        private string DELETE_SUCCESSFULLY = "DELETE_SUCCESSFULLY";
        public const string CanNewProperty = "CanNew";
        public const string CanCancelProperty = "CanCancel";
        public const string CanSaveProperty = "CanSave";
        public const string CanDeleteProperty = "CanDelete";
        public const string CanFinishProperty = "CanFinish";
        public const string CanPrintProperty = "CanPrint";
        public const string IsDataChangedProperty = "IsDataChanged";
        public const string IsNewProperty = "IsNew";
        public const string CurrentUserRightProperty = "CurrentUserRight";
        public const string ACCESS_DENIED = "ACCESS_DENIED";
        public const string SECURITY = "Warning";
        public const string INFORMATION_CAPTION = "INFORMATION_CAPTION";
        public const string CODE_DOES_NOT_EXIST = "CODE_DOES_NOT_EXIST";
        private const string SAVE_SUCCESSFULLY = "GEN_SAVE_SUCCESSFULLY";
        private const string GEN_DELETE_SUCCESSFULLY = "GEN_DELETE_SUCCESSFULLY";
        //used for creating export template
        private const int HEADER_ROW = 2;
        private const string TEMPLATE_PATH = @"c:\test.xls";
        private const string VIEW_IMPORT_LOG_FILE = "ViewImportLogFile";
        private const string TEMPLATE_EXPORTED = "TemplateExported";
        private const string TEMPLATE_EXPORT_FAILED = "TemplateExportFailed";

        #endregion
        public FormEntryBase()
        {
            InitializeComponent();
        }

        public FormEntryBase(string functionID)
        {
            InitializeComponent();
            this.functionID = functionID;
            //ApplyPermission();            
        }

        #region Public Interface

        //Default value for CanNew must be True.
        bool canNew = true;
        public bool CanNew
        {
            get { return canNew; }
            set
            {
                canNew = value && isUserCanNew && isWrite;
                OnPropertyChanged(FormEntryBase.CanNewProperty);
            }
        }

        bool canCancel = false;
        public bool CanCancel
        {
            get { return canCancel; }
            set
            {
                canCancel = value && isUserCanCancel && isWrite;
                OnPropertyChanged(FormEntryBase.CanCancelProperty);
            }
        }

        bool canSave = false;
        public bool CanSave
        {
            get { return canSave; }
            set
            {
                canSave = value && isUserCanSave && isWrite;
                OnPropertyChanged(FormEntryBase.CanSaveProperty);
            }
        }

        bool canDelete = false;
        public bool CanDelete
        {
            get { return canDelete; }
            set
            {
                canDelete = value && isUserCanDelete && isDelete;
                OnPropertyChanged(FormEntryBase.CanDeleteProperty);
            }
        }

        bool canFinish = false;
        public bool CanFinish
        {
            get { return canFinish; }
            set
            {
                canFinish = value && isUserCanFinish && isWrite;
                OnPropertyChanged(FormEntryBase.CanFinishProperty);
            }
        }

        bool canPrint = false;
        public bool CanPrint
        {
            get { return canPrint; }
            set
            {
                canPrint = value;
                //canCancel = value && isUserCanCancel && isWrite;
                OnPropertyChanged(FormEntryBase.CanPrintProperty);
            }
        }

        //UserRight currentRight = null;
        //public UserRight CurrentUserRight
        //{
        //    get
        //    {
        //        if (CurrentUser != null && CurrentUser.UserRights != null)
        //        {
        //            currentRight = CurrentUser.UserRights.Find(r => r.FunctionID.Equals(functionID));
        //        }
        //        return currentRight;
        //    }
        //}

        bool isEnableEventHandler = true;
        private bool EnableEventHandler
        {
            get { return isEnableEventHandler; }
            set
            {
                isEnableEventHandler = value;
            }
        }

        bool isNeedToValidateDataChange = true;
        public bool NeedToValidateDataChange
        {
            get { return isNeedToValidateDataChange; }
            set
            {
                isNeedToValidateDataChange = value;
            }
        }

        bool isReadOnly = false;
        public bool IsReadOnlyControls
        {
            get { return isReadOnly; }
            set
            {
                isReadOnly = value;

                if (isReadOnly == true)
                {
                    ForceToValidate = false;
                    //isEnableEventHandler = false;
                    NeedToValidateDataChange = false;
                    //ApplyRulesForEntity(true, false, false, false, false);
                }
                else
                {
                    ForceToValidate = true;
                    //isEnableEventHandler = true;
                    NeedToValidateDataChange = true;
                    //ApplyRulesForEntity(true, true, true, true, true);
                }
                ClearStatusMessage();
                ApplyReadOnly(this, isReadOnly);
            }
        }
        #endregion

        #region Entity and rules
        private IBaseEntity entitybackup = null;
        private IBaseEntity entity = null;

        protected override IBaseEntity Entity
        {
            get { return entity; }
            set
            {
                if (entity != null)
                {
                    entity.PropertyChanged -= Entity_PropertyChanged;
                }

                if (value != null)
                {
                    entity = value;
                    entitybackup = (IBaseEntity)value.Clone();
                }

                if (entity != null)
                {
                    BindingToControls(entity);
                    isEnableEventHandler = true && !isReadOnly;
                    IsNew = false;
                    IsDataChanged = false;
                    entity.PropertyChanged += Entity_PropertyChanged;
                }
            }
        }

        bool isDataChanged = false;
        protected virtual bool IsDataChanged
        {
            get
            {
                return isDataChanged;
            }
            set
            {
                if (value == true || isReadOnly == true)
                {
                    ClearStatusMessage();
                }
                isDataChanged = (value && !isReadOnly);

                OnPropertyChanged(FormEntryBase.IsDataChangedProperty);
            }
        }

        bool isNew = false;
        public bool IsNew
        {
            get { return isNew; }
            set
            {
                isNew = value;

                if (this.AutoControlButtons)
                {
                    if (isNew == true)
                    {
                        CanNew = true;// false;
                        CanSave = true;// false;
                        CanCancel = true;// false;
                        CanDelete = false;
                        CanFinish = true;// false;
                    }
                    else
                    {
                        CanNew = true;
                        CanSave = true;// false;
                        CanCancel = true;// false;
                        CanDelete = true;
                        CanFinish = true;
                    }
                }
                IsNewChanged();
                OnPropertyChanged(FormEntryBase.IsNewProperty);
            }
        }
        public virtual void IsNewChanged()
        {

        }
        public bool CanClose
        {
            get;
            protected set;
        }
        bool autoControlButtons = true;
        protected bool AutoControlButtons
        {
            get { return this.autoControlButtons; }
            set
            {
                this.autoControlButtons = value;

                if (!this.autoControlButtons)
                {
                    this.CanCancel = true;
                    this.CanDelete = true;
                    this.CanFinish = true;
                    this.CanNew = true;
                    this.CanSave = true;
                }
            }
        }

        private bool isUserCanNew = true;
        private bool isUserCanSave = true;
        private bool isUserCanCancel = true;
        private bool isUserCanDelete = true;
        private bool isUserCanFinish = true;

        public void ApplyRulesForEntity(bool UserCanNew = true, bool UserCanSave = true, bool UserCanCancel = true, bool UserCanDelete = true, bool UserCanFinish = true)
        {
            isUserCanNew = UserCanNew;
            isUserCanSave = UserCanSave;
            isUserCanCancel = UserCanCancel;
            isUserCanDelete = UserCanDelete;
            isUserCanFinish = UserCanFinish;

            if ((isUserCanNew == false) && (isUserCanSave == false) && (isUserCanCancel == false) && (isUserCanDelete == false))
            {
                IsReadOnlyControls = true;
            }
        }

        public void ResetRulesForEntity()
        {
            isUserCanNew = true;
            isUserCanSave = true;
            isUserCanCancel = true;
            isUserCanDelete = true;
            isUserCanFinish = true;
        }

        //private bool isRead = false;
        //private bool isWrite = false;
        //private bool isDelete = false;

        private bool isRead = true;
        private bool isWrite = true;
        private bool isDelete = true;

        //public void ApplyPermission()
        //{
        //    if (CurrentUserRight != null && (CurrentUserRight.isRead || CurrentUserRight.isWrite || CurrentUserRight.isDelete))
        //    {
        //        if (this is FormManualBase)
        //        {
        //            isRead = true;
        //            isWrite = false;
        //            isDelete = false;
        //        }
        //        else
        //        {
        //            isRead = currentRight.isRead;
        //            isWrite = currentRight.isWrite;
        //            isDelete = currentRight.isDelete;
        //        }

        //        CanDelete = CurrentUserRight.isDelete;
        //        if (currentRight.isWrite)
        //        {
        //            CanNew = true;
        //            CanCancel = true;
        //            CanSave = true;
        //            CanFinish = true;
        //            isEnableEventHandler = true && !isReadOnly;
        //        }
        //        else
        //        {
        //            CanNew = false;
        //            CanCancel = false;
        //            CanSave = false;
        //            CanFinish = false;
        //            isEnableEventHandler = false;
        //        }
        //    }
        //    else
        //    {
        //        try
        //        {
        //            MessageBox.Show(Messages.GetString(ACCESS_DENIED));
        //            this.ForceClose = true;
        //            this.Close();
        //        }
        //        catch (Exception e)
        //        {
        //            ShowErrorMessage(e);
        //        }
        //    }
        //}
        #endregion

        #region Private functions
        private void UpdateDataChange()
        {
            try
            {
                if (isReadOnly == false && isEnableEventHandler == true && isNeedToValidateDataChange == true)
                {
                    if (IsDataChanged == false)
                    {
                        if (IsNew == false)
                        {

                            if ((CanNew == true && CanSave == true && CanCancel == true && CanFinish == true))
                            {
                                if (IsDataChanged == false)
                                {
                                    IsDataChanged = true;
                                }
                            }
                        }
                        else if (IsNew == true)
                        {
                            if ((CanNew == true && CanSave == true && CanCancel == true && CanFinish == true))
                            {
                                if (IsDataChanged == false)
                                {
                                    IsDataChanged = true;
                                }
                            }
                        }
                    }
                    else
                    {
                        if (tbStatusInfo.Visible == true)
                        {
                            ClearStatusMessage();
                        }
                    }
                }
            }
            catch (Exception ex)
            {

                ShowErrorMessage(ex);
            }
        }

        private void SetEventHandler(Control control)
        {
            try
            {
                PreSetupProperties(control);

                if ((control is TextEdit) ||
                   (control is ComboBoxEdit) ||
                   (control is DateEdit) ||
                   (control is ButtonEdit))
                {
                    if (control.Tag == null)
                    {
                        (control as TextEdit).EditValueChanged += (sender, e) =>
                        {
                            UpdateDataChange();
                        };
                    }
                    (control as TextEdit).Enter += (sender, e) =>
                    {
                        (control as TextEdit).SelectAll();
                    };
                    //(control as TextEdit).EnterMoveNextControl = true;
                }
                else if ((control is RadioButton) ||
                   (control is CheckEdit))
                {
                    (control as CheckEdit).CheckedChanged += (sender, e) =>
                    {
                        UpdateDataChange();
                    };

                    (control as CheckEdit).KeyPress += (sender, e) =>
                    {
                        if (e.KeyChar == 13)
                        {
                            if (SelectNextControl(control, true, true, true, true) == false)
                            {
                                SelectNextControl(control, false, true, true, true);
                            }
                        }
                    };
                }
                else if (control is XtraTabControl)
                {
                    (control as XtraTabControl).KeyPress += (sender, e) =>
                    {
                        if (e.KeyChar == 13)
                        {
                            XtraTabPage page = (control as XtraTabControl).SelectedTabPage;
                            if (page != null)
                            {
                                if (SelectNextControl(page, true, true, true, true) == false)
                                {
                                    SelectNextControl(page, false, true, true, true);
                                }
                            }
                        }
                    };
                }
                else if (control is GridControl)
                {
                    GridView grdview = (control as GridControl).FocusedView as GridView;
                    if (grdview != null)
                    {
                        grdview.CellValueChanged += (sender, e) =>
                        {
                            IsDataChanged = true;
                        };
                        grdview.CellValueChanging += (sender, e) =>
                        {
                            IsDataChanged = true;
                        };
                    }

                    (control as GridControl).ProcessGridKey += (object sender, System.Windows.Forms.KeyEventArgs e) =>
                    {
                        if (e.KeyCode == Keys.Tab)
                        {
                            GridControl grid = sender as GridControl;
                            GridView view = grid.FocusedView as GridView;
                            if (((e.Modifiers == Keys.None) && view.IsLastRow && (view.FocusedColumn != null) && (view.FocusedColumn.VisibleIndex == view.VisibleColumns.Count - 1))
                                || ((e.Modifiers == Keys.Shift) && view.IsFirstRow && (view.FocusedColumn.VisibleIndex == 0))
                                || (view.RowCount == 0)
                                || (view.IsNewItemRow(view.FocusedRowHandle) && (view.FocusedColumn != null) && (view.FocusedColumn.VisibleIndex == view.VisibleColumns.Count - 1)))
                            {
                                try
                                {
                                    if (view.IsEditing)
                                    {
                                        view.CloseEditor();
                                    }

                                    SelectNextControl(grid, e.Modifiers == Keys.None, true, true, true);
                                    e.Handled = false;
                                }
                                catch
                                {
                                }
                            }
                        }
                    };
                }

                foreach (Control child in control.Controls)
                {
                    SetEventHandler(child);
                }
            }
            catch (Exception ex)
            {

                ShowErrorMessage(ex);
            }
        }

        private void ApplyReadOnly(Control control, bool bReadOnly)
        {
            try
            {

                if ((control is TextEdit) ||
                    (control is ComboBoxEdit) ||
                    (control is DateEdit) ||
                    (control is ButtonEdit))
                {
                    if (control.Tag == null)
                    {
                        (control as TextEdit).Properties.ReadOnly = bReadOnly;
                        if ((control is ButtonEdit) || (control is DateEdit))
                        {
                            if (bReadOnly == true)
                            {
                                //(control as ButtonEdit).BackColor = Color.WhiteSmoke;                            
                            }
                            //else
                            //{
                            //    (control as ButtonEdit).BackColor = Color.White;
                            //}

                            (control as ButtonEdit).Properties.Buttons[0].Enabled = !bReadOnly;
                        }
                    }

                }
                else if (control is SimpleButton)
                {
                    (control as SimpleButton).Enabled = !bReadOnly;
                }
                else if ((control is RadioButton) ||
                    (control is CheckEdit))
                {
                    (control as CheckEdit).Properties.ReadOnly = bReadOnly;
                }
                else if (control is GridControl)
                {
                    foreach (GridView view in (control as GridControl).Views)
                    {
                        view.OptionsBehavior.Editable = !bReadOnly;


                        //foreach (GridColumn column in (view as GridView).Columns)
                        //{
                        //    if (bReadOnly == true)
                        //    {
                        //        column.AppearanceCell.BackColor = Color.White;
                        //    }
                        //    column.OptionsColumn.AllowSort = DevExpress.Utils.DefaultBoolean.False;
                        //}                    
                    }
                }

                foreach (Control child in control.Controls)
                {
                    ApplyReadOnly(child, bReadOnly);
                }
            }
            catch (Exception ex)
            {

                ShowErrorMessage(ex);
            }
        }

        #endregion

        #region Public Events
        public void DoNew()
        {
            try
            {
                ForceToValidate = false;
                if (IsDataChanged)
                {
                    var result = ShowNewConfirmMessage();
                    if (result == DialogResult.Cancel)
                    {
                        ForceToValidate = true;
                        return;
                    }

                    if (result == DialogResult.Yes)
                    {
                        if (!DoSave())
                        {
                            ForceToValidate = true;
                            return;
                        }
                    }
                }

                //New();
                if (IsNew)
                {
                    ClearData();
                    ClearStatusMessage();
                }
                else
                {
                    New();
                }

                IsDataChanged = false;
                ReActiveControl();
            }
            catch (Exception ex)
            {
                ShowErrorMessage(ex);
            }
        }

        /// <summary>
        /// Check validate values, Call Save(),Set IsDataChanged = false
        /// And return Saved status(true or false)
        /// </summary>
        public bool DoSave()
        {
            //if (currentRight.isWrite)
            //{
                if (!m_isImporting)
                {
                    if (IsDataChanged == false) return false;
                }

                txtFocus.Focus();
                ClearStatusMessage();

                if (!ValidateControls()) return false;
                try
                {
                    if (Save() == true)
                    {
                        IsNew = false;
                        IsDataChanged = false;

                        ShowSaveSuccedMessage();
                        ReActiveControl();

                        return true;
                    }
                }
                catch (Exception ex)
                {
                    ShowErrorMessage(ex);
                }
            //}
            //else
            //{
            //    MessageBox.Show(this, Messages.GetString(ACCESS_DENIED), Messages.GetString(SECURITY));
            //}
            return false;
        }

        public virtual void DoDelete()
        {
            //if (CanDelete && currentRight.isDelete)
            //{
                if (IsNew)
                {
                    DoNew();
                }
                else if (ShowDeleteConfirmMessage() == DialogResult.Yes)
                {
                    try
                    {
                        if (Delete() == true)
                        {
                            bool tmp = isEnableEventHandler;
                            isEnableEventHandler = false;
                            New();
                            isEnableEventHandler = tmp;
                            ReActiveControl();
                            ShowSuccessMessage(Messages.GetString(GEN_DELETE_SUCCESSFULLY));
                            this.DialogResult = DialogResult.OK;
                        }
                    }
                    catch (Exception ex)
                    {
                        ShowErrorMessage(ex);
                    }
                }
            //}
            //else
            //{
            //    MessageBox.Show(this, Messages.GetString(ACCESS_DENIED), Messages.GetString(SECURITY));
            //}
        }

        public void DoCancel()
        {
            if (IsDataChanged == true)
            {
                if (!(ShowCancelConfirmMessage() == DialogResult.Yes))
                    return;
                else
                {
                    this.DialogResult = DialogResult.Cancel;
                }
            }

            //this.ClearData(); //@@TODO:it's no need to clear data here            
            Cancel();

            IsDataChanged = false;

            ClearStatusMessage();
            RemoveControlError();
            ReActiveControl();
        }

        public virtual void DoFinish()
        {
            bool saved = true;
            if (IsDataChanged)
            {
                saved = DoSave();
            }

            if (saved)
            {
                DoNew();
            }
        }

        public virtual void DoPrint()
        {
            if (CanPrint)
            {
                Print();
            }
        }

        private void releaseObject(object obj)
        {
            try
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
                obj = null;
            }
            catch (Exception ex)
            {
                obj = null;
                MessageBox.Show("Unable to release the Object " + ex.ToString());
            }
            finally
            {
                GC.Collect();
            }
        }

        public void DoImport(object path)
        {
            try
            {
                DoImportDataFromFile(path);
            }
            finally
            {
                m_isImporting = false;
            }
        }

        public List<string> TemplateColumnHeader { get; private set; }


        private delegate void UpdateGUIDelegate(string controlName, object value);
        private void DoSetControlValue(object data/*string controlName, object value*/)
        {
            try
            {
                object[] arg = data as object[];
                if (arg != null && arg.Length == 2)
                {

                    string crlName = DataConvertUltils.ToString(arg[0]);
                    object val = arg[1];

                    if (this.InvokeRequired)
                    {
                        UpdateGUIDelegate GUIDelegate = new UpdateGUIDelegate(SetControlValue);
                        this.Invoke(GUIDelegate, new object[] { crlName, val });
                    }
                    else
                    {
                        SetControlValue(crlName, val);
                    }
                }
            }
            catch (Exception ex)
            {

                ShowErrorMessage(ex);
            }
        }

        private void SetControlValue(string controlName, object value)
        {
            try
            {
                if (value != null)
                {
                    Control[] matches = this.Controls.Find(controlName, true);
                    if (matches != null && matches.Length > 0)
                    {
                        Control current = matches[0] as Control;
                        current.Focus();

                        if (current is CheckEdit)
                        {
                            (current as CheckEdit).Checked = false;
                            bool val = DataConvertUltils.ToBoolean(value);
                            (current as CheckEdit).Checked = val;
                        }
                        else
                        {
                            if (current is DateEdit)
                            {
                                (current as TextEdit).EditValue = DataConvertUltils.ToDateTimeFromOADate(value);
                            }
                            else if (current is ComboBoxEdit)
                            {
                                SetComboValue(current as ComboBoxEdit, DataConvertUltils.ToString(value));
                            }
                            else
                            {
                                (current as TextEdit).EditValue = value;
                            }
                        }
                    }
                }
            }
            catch
            {
            }
        }

        private void SetComboValue(ComboBoxEdit cbo, string value)
        {
            if (cbo.Properties.Items.Count == 1 && string.IsNullOrEmpty(DataConvertUltils.ToString(cbo.Properties.Items[0])))
            {
                cbo.EditValue = DataConvertUltils.ToString(value);
            }
            else
            {
                for (int i = 0, len = cbo.Properties.Items.Count; i < len; i++)
                {
                    if (DataConvertUltils.ToString(cbo.Properties.Items[i]).Equals(value))
                    {
                        cbo.SelectedIndex = i;
                        break;
                    }
                }
            }
        }

        private delegate void ImportDataDelegate(string path);

        private void DoImportDataFromFile(object path)
        {
            //m_isImporting = true;
            //if (this.InvokeRequired)
            //{
            //    ImportDataDelegate importDelegate = new ImportDataDelegate(ImportDataFromFile);
            //    this.Invoke(importDelegate, new object[] { path });
            //}
            //else
            //{
            //    //ImportDataFromFile(DataConvertUltils.ToString(path));
            //}
        }

    
        /// <summary>
        /// Filter control's name that was extracted from excel template file. These names will be used for importing data
        /// </summary>
        /// <param name="controls"><see cref="TemplateColumnHeader"/></param>
        /// <returns></returns>
        protected virtual List<string> FilterControlName(List<string> controls)
        {
            return controls;
        }

        //private List<ItemTemplate> m_ControlToExport;
        ///// <summary>
        ///// Extract all the appropriate controls that can be used in template
        ///// </summary>
        ///// <returns>D</returns>
        //private List<ItemTemplate> ExtractFormControls()
        //{
        //    List<ItemTemplate> controlToExport = new List<ItemTemplate>();
        //    GetControls(this, controlToExport);

        //    controlToExport = FilterItemTemplate(controlToExport);

        //    return controlToExport;
        //}

        ///// <summary>
        ///// Filter ItemTemplate that will be used for exporting template
        ///// </summary>
        ///// <param name="list"></param>
        ///// <returns></returns>
        //protected virtual List<ItemTemplate> FilterItemTemplate(List<ItemTemplate> list)
        //{
        //    return list;
        //}

        //private void GetControls(Control control, List<ItemTemplate> m_ControlToExport)
        //{
        //    try
        //    {
        //        foreach (Control ctrl in control.Controls)
        //        {
        //            if (//ctrl is LabelControl
        //                //|| ctrl is XtraTabPage
        //                //|| ctrl is GroupBox
        //                //|| ctrl is GroupControl
        //                //|| ctrl is Button
        //                //|| ctrl is LinkLabel
        //                //ctrl is SimpleButton
        //                //|| ctrl is Panel
        //              ctrl is CheckEdit
        //              || ctrl is TextEdit
        //                //|| ctrl is Label
        //            )
        //            {
        //                if (!m_ControlToExport.Exists(i => i.Name.Equals(ctrl.Name)))
        //                {
        //                    bool isRequired = false;
        //                    if (ctrl.BackColor.Equals(Constants.REQUIRE_COLOR))
        //                    {
        //                        isRequired = true;
        //                    }
        //                    m_ControlToExport.Add(new ItemTemplate() { Name = ctrl.Name, DisplayText = ctrl.Name, IsRequired = isRequired });
        //                }
        //            }
        //            else if (ctrl is XtraTabControl)
        //            {
        //                ActivatePagesOfTabControl(ctrl as XtraTabControl);
        //            }
        //            /*else if (ctrl is GridControl)
        //            {
        //                foreach (GridView view in (ctrl as GridControl).Views)
        //                {
        //                    foreach (GridColumn column in view.Columns)
        //                    {
        //                        column.AppearanceHeader.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Near;
        //                        string text = FormResources.GetString(this.Name + "." + column.Name);
        //                        if (!string.IsNullOrEmpty(text))
        //                        {
        //                            column.Caption = text;
        //                        }
        //                    }
        //                }
        //            }*/
        //            else if (ctrl is LayoutControl)
        //            {
        //                foreach (var item in ((LayoutControl)ctrl).Root.Items)
        //                {
        //                    if (item is LayoutControlItem && !(item is EmptySpaceItem))
        //                    {
        //                        LayoutControlItem currentItem = item as LayoutControlItem;
        //                        AddItem(currentItem, m_ControlToExport);
        //                    }
        //                    else if (item is LayoutControlGroup)
        //                    {
        //                        LayoutControlGroup currentItemGroup = item as LayoutControlGroup;
        //                        foreach (var i in currentItemGroup.Items)
        //                        {
        //                            if (i is LayoutControlItem && !(i is EmptySpaceItem))
        //                            {
        //                                LayoutControlItem currentItem = i as LayoutControlItem;
        //                                AddItem(currentItem, m_ControlToExport);
        //                            }
        //                        }
        //                    }
        //                }
        //            }
        //            if (ctrl.Controls.Count > 0)
        //            {
        //                GetControls(ctrl, m_ControlToExport);
        //            }
        //        }
        //    }
        //    catch (Exception ex)
        //    {

        //        ShowErrorMessage(ex);
        //    }
        //}

        //private void AddItem(LayoutControlItem currentItem, List<ItemTemplate> list)
        //{
        //    try
        //    {
        //        if (!(currentItem.Control is LabelControl)
        //                 && !(currentItem.Control is XtraTabControl)
        //                 && !(currentItem.Control is PanelControl)
        //            //&& !(currentItem.Control is ButtonEdit)
        //                 && !(currentItem.Control is SimpleButton)
        //                 && !(currentItem.Control is GridControl))
        //        {
        //            if (!list.Exists(i => i.Name.Equals(currentItem.ControlName)))
        //            {
        //                bool isRequired = false;
        //                if (currentItem.Control.BackColor.Equals(Constants.REQUIRE_COLOR))
        //                {
        //                    isRequired = true;
        //                }
        //                if (currentItem.Control is CheckEdit && !string.IsNullOrEmpty((currentItem.Control as CheckEdit).Text))
        //                {

        //                    list.Add(new ItemTemplate() { Name = currentItem.Control.Name, DisplayText = currentItem.Control.Text, IsRequired = isRequired });
        //                }
        //                else
        //                {
        //                    list.Add(new ItemTemplate() { Name = currentItem.ControlName, DisplayText = currentItem.Text, IsRequired = isRequired });
        //                }
        //            }
        //        }
        //    }
        //    catch (Exception ex)
        //    {

        //        ShowErrorMessage(ex);
        //    }
        //}

        #region Property Changed

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion

        #region Form Event

        protected override void WndProc(ref Message m)
        {
            const int WM_NCRBUTTONDOWN = 0xA4;

            if (m.Msg == WM_NCRBUTTONDOWN)
            {
                OnPropertyChanged("ShowPopup");
            }
            else
            {
                base.WndProc(ref m);
            }
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            txtFocus.Focus();
            CanClose = true;
            if (IsDataChanged)
            {
                var result = ShowSaveConfimMessage();
                if (result == DialogResult.Yes)
                {
                    CanClose = DoSave();
                    e.Cancel = !CanClose;
                }
                else if (result == DialogResult.Cancel)
                {
                    this.CausesValidation = false;
                    e.Cancel = true;
                }
            }
            base.OnFormClosing(e);
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            ClearStatusMessage();
            SetEventHandler(this);
        }

        protected override void OnShown(EventArgs e)
        {
            base.OnShown(e);

            //if (IsLoggedIn)
            //{
                InitializeData();
                InitValidationRules();
            //}
        }

        #endregion

        protected virtual void InitValidationRules() { }

        protected virtual void InitializeData() { }

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            return base.ProcessCmdKey(ref msg, keyData);
        }
        #endregion

        #region Protected Events
        public virtual void New()
        {
            //isEnableEventHandler = false;
            isDataChanged = false;
            IsNew = true;
        }

        protected virtual bool Delete()
        { throw new Exception("please override function Delete"); }

        protected virtual bool Save()
        {
            throw new Exception("please override function Save");
        }

        protected virtual void Print()
        {
            throw new Exception("please override function Print");
        }

        public virtual void Cancel()
        {
            //Keep current status
            bool isNew = IsNew;
            if (isNew)
            {
                New();
                IsDataChanged = false;
            }
            else if (entitybackup != null)
            {
                Entity = entitybackup;
                IsNew = isNew;// Re-asign current status.
            }
            //else
            //{
            //    New();
            //    IsDataChanged = false;
            //}
        }

        private void ReActiveControl()
        {
            ForceToValidate = false;
            FocusFirtsControl();
            ForceToValidate = true;
        }

        protected void Entity_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            IsDataChanged = true;
        }

        protected virtual void BindingToControls(IBaseEntity entity)
        {
            RemoveControlError();
        }

        protected virtual void ClearData()
        {
            if (Entity != null)
            {
                //var type = Entity.GetType();
                //var newInstance = Activator.CreateInstance(type);

                //foreach (var p in type.GetProperties())
                //{
                //    var value = p.GetValue(Entity, null);

                //    if (value is ICloneable)
                //    {
                //        p.SetValue(Entity, ((ICloneable)value).Clone(), null);
                //    }
                //    p.SetValue(Entity, value, null);
                //}

                foreach (var p in Entity.GetType().GetProperties())
                    if (p.CanWrite)
                        p.SetValue(Entity, null, null);
            }

            IsDataChanged = false;
            RemoveControlError();
        }
        #endregion

        #region Messages
        /// <summary>
        /// Show error message in status bar.
        /// </summary>
        /// <param name="message"></param>
        protected void ShowErrorMessage(string message)
        {
            tbStatusInfo.ToolTipText = message;
            tbStatusInfo.Visible = true;

            Graphics graphics = CreateGraphics();
            SizeF textSize = graphics.MeasureString(message, Font);

            int pixcellPerText = (int)(textSize.Width / message.Length);
            int capbalitive = (Width - 80) / pixcellPerText;

            if (capbalitive < message.Length)
            {
                capbalitive = message.LastIndexOf(' ', capbalitive);
                message = message.Substring(0, capbalitive) + " ...";
            }
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormEntryBase));
            tbStatusInfo.Image = ((System.Drawing.Image)(resources.GetObject("tbStatusInfo.Image")));
            tbStatusInfo.Text = string.Format(Messages.GetString("TitleErrorMessage") + ": {0}", message);
            tbStatusInfo.ForeColor = Color.Red;
            tbStatusInfo.Width = Width - 30;

            timer.Start();
            count = 0;
        }

        /// <summary>
        /// Show error message in status bar.
        /// </summary>
        /// <param name="message"></param>
        protected void ShowSuccessMessage(string message)
        {
            tbStatusInfo.ToolTipText = message;
            tbStatusInfo.Visible = true;

            Graphics graphics = CreateGraphics();
            SizeF textSize = graphics.MeasureString(message, Font);

            int pixcellPerText = (int)(textSize.Width / message.Length);
            int capbalitive = (Width - 80) / pixcellPerText;

            if (capbalitive < message.Length)
            {
                capbalitive = message.LastIndexOf(' ', capbalitive);
                message = message.Substring(0, capbalitive) + " ...";
            }
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormEntryBase));
            tbStatusInfo.Image = ((System.Drawing.Image)(resources.GetObject("tbStatusInfo.ImageSuccess")));
            tbStatusInfo.Text = string.Format("{0}", message);
            tbStatusInfo.ForeColor = Color.Blue;
            tbStatusInfo.Width = Width - 30;            

            timer.Start();
            count = 0;
        }


        /// <summary>
        /// Clear error message in status bar.
        /// </summary>
        protected virtual void ClearErrorMessage()
        {
            //tbStatusInfo.Text = string.Empty;
            //tbStatusInfo.ToolTipText = string.Empty;
            //tbStatusInfo.Visible = false;           
        }
        protected override void ClearStatusMessage()
        {
            tbStatusInfo.Text = string.Empty;
            tbStatusInfo.ToolTipText = string.Empty;
            tbStatusInfo.Visible = false;
        }
        /// <summary>
        /// Show confirm message when cancel button clicked
        /// </summary>
        /// <returns>DialogResult.YesNo</returns>
        protected virtual DialogResult ShowCancelConfirmMessage()
        {
            return MessageBox.Show(
                PMS.Resources.Messages.GetString(Constants.CANCEL_CONFIRM_MESSAGE),
                PMS.Resources.Messages.GetString(Constants.TITLE_CONFIRM_MESSAGE),
                 MessageBoxButtons.YesNo, MessageBoxIcon.Question);
        }

        /// <summary>
        /// Show confirm message when deleted button clicked
        /// </summary>
        /// <returns>DialogResult.YesNo</returns>
        protected DialogResult ShowDeleteConfirmMessage()
        {
            DialogResult result = MessageBox.Show(
                PMS.Resources.Messages.GetString(Constants.GEN_CONFIRM_DELETE),
                PMS.Resources.Messages.GetString(Constants.TITLE_CONFIRM_MESSAGE),
                MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);

            //if (DialogResult.OK == result || DialogResult.Yes == result)
            //{
            //    if (!currentRight.isDelete)
            //    {
            //        MessageBox.Show(this, Messages.GetString(ACCESS_DENIED), Messages.GetString(SECURITY));
            //        result = System.Windows.Forms.DialogResult.No;
            //    }
            //}

            return result;
        }

        /// <summary>
        /// Show confirm message when new button clicked
        /// </summary>
        /// <returns>DialogResult.YesNoCancel</returns>
        protected DialogResult ShowNewConfirmMessage()
        {
            if (!AllowShowMessage())
            {
                return DialogResult.Yes;
            }
            else
            {
                return MessageBox.Show(
                     PMS.Resources.Messages.GetString(Constants.NEW_CONFIRM_MESSAGE),
                     PMS.Resources.Messages.GetString(Constants.TITLE_CONFIRM_MESSAGE),
                      MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            }
        }

        /// <summary>
        /// Show confirm message when form closing
        /// </summary>
        /// <returns>DialogResult.YesNoCancel</returns>
        protected DialogResult ShowSaveConfimMessage()
        {
            DialogResult result;
            if (!AllowShowMessage())
            {
                result = DialogResult.Yes;
            }
            else
            {
                result = MessageBox.Show(
                     PMS.Resources.Messages.GetString(Constants.SAVE_CONFIRM_MESSAGE),
                     PMS.Resources.Messages.GetString(Constants.TITLE_CONFIRM_MESSAGE),
                      MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);

                //if (DialogResult.Yes == result)
                //{
                //    if (!currentRight.isWrite)
                //    {
                //        MessageBox.Show(this, Messages.GetString(ACCESS_DENIED), Messages.GetString(SECURITY));
                //        result = DialogResult.No;
                //    }
                //}
            }
            return result;
        }

        protected virtual void ShowSaveSuccedMessage()
        {
            if (!AllowShowMessage())
            {
                return;
            }
            ShowSuccessMessage(Messages.GetString(SAVE_SUCCESSFULLY));
        }

        protected virtual void ShowDeleteSuccedMessage()
        {
            if (!AllowShowMessage())
            {
                return;
            }
            ShowSuccessMessage(Messages.GetString(DELETE_SUCCESSFULLY));
        }

        protected void ShowInfoMessage(string title, string message)
        {
            MessageBox.Show(message, title, MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        protected void ShowCodeDoesNotExistMessage(string code)
        {
            if (!AllowShowMessage())
            {
                return;
            }
            string message = string.Format(Messages.GetString(CODE_DOES_NOT_EXIST), code);
            ShowInfoMessage(Messages.GetString(INFORMATION_CAPTION), message);
        }

        private bool AllowShowMessage()
        {
            return !m_isImporting;
        }
        #endregion

        #region Form override
        int count = 0;
        
        private void timer_Tick(object sender, EventArgs e)
        {
            if (tbStatusInfo.Visible)
                tbStatusInfo.Enabled = !tbStatusInfo.Enabled;
            else timer.Stop();

            count++;

            if (count >= 10)
            {
                tbStatusInfo.Enabled = true;
                timer.Stop();
                count = 0;
            }
        }

        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
        }
        #endregion
    }
}